package com.zon.len.mp.extend.configuration;

import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.BeansException;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


/**
 * @author ZonLen since on 2021/10/8 下午12:55
 */
@Slf4j
@Configuration
public class MybatisPlusPaginationConfiguration implements ApplicationContextAware,
    ApplicationRunner {

  /**
   * 分页插件
   */
  @Bean
  @ConditionalOnProperty(name = "mybatis.plus.pagination.enable", havingValue = "true", matchIfMissing = true)
  public MybatisPlusInterceptor paginationInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    PaginationInnerInterceptor innerInterceptor = new PaginationInnerInterceptor();
    innerInterceptor.setMaxLimit(30000L);
    interceptor.addInnerInterceptor(innerInterceptor);
    return interceptor;
  }

  /**
   * 分库分表插件
   */
  @Bean
  public MybatisPlusShardingInterceptor shardingInterceptor() {
    return new MybatisPlusShardingInterceptor();
  }

  /**
   * @see DefaultSqlInjector SQL注入器
   */
  @Bean
  public ExtendSqlInjector extendSqlInjector() {
    return new ExtendSqlInjector();
  }

  private ApplicationContext applicationContext;

  @Override
  public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
  }

  /**
   * 启动对Mybatis plugin 进行优先级处理
   */
  @Override
  public void run(ApplicationArguments args) {
    final SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class);
    sqlSessionFactory.getConfiguration().getInterceptors().stream()
        .filter(interceptor -> interceptor instanceof MybatisPlusShardingInterceptor).findFirst()
        .ifPresent(interceptor -> sqlSessionFactory.getConfiguration().addInterceptor(interceptor));
  }
}
